package org.yoki.edu.common.protocol.radius.msg.packet;

import org.yoki.edu.common.protocol.radius.attribute.attr.RadiusMsgAttr;
import org.yoki.edu.common.protocol.radius.attribute.parser.RadiusMsgAttrParser;
import org.yoki.edu.common.protocol.radius.exception.RadiusException;
import org.yoki.edu.common.utils.encrypt.EncryptUtils;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Sky$
 * @Description: TODO
 * @date 2018/1/16$ 14:40$
 */
public abstract class RespRadiusMsg extends RadiusMsg {

    protected RadiusMsg reqMsg;

    public RespRadiusMsg(String secret, RadiusMsg reqMsg) {
        super(secret);
        this.reqMsg = reqMsg;
    }

    /**
     * Code+ID+Length+RequestAuth+Attributes+Secret
     *
     * @param byteWithoutAuthenticator
     * @return
     */
    @Override
    protected byte[] getAuthenticatorBytes(byte[] byteWithoutAuthenticator) {
        if (null == reqMsg) {
            throw new NullPointerException();
        }
        byte[] out = byteWithoutAuthenticator;
        byte[] secretBytes = secret.getBytes();
        byte[] requestAuthenticator = reqMsg.getAuthenticator();
        byte[] tempBytes = new byte[out.length + secretBytes.length];

        System.arraycopy(out, 0, tempBytes, 0, out.length);
        System.arraycopy(requestAuthenticator, 0, tempBytes, INDEX_AUTHENTICATOR, LENGTH_AUTHENTICATOR);
        System.arraycopy(secretBytes, 0, tempBytes, out.length, secretBytes.length);
        return EncryptUtils.encryptMD5Bytes(tempBytes);
    }

    @Override
    protected void parseAttributes(List<byte[]> attrBytesList) throws RadiusException {
        if (null == attributes) {
            attributes = new ArrayList<>();
        }
        if (null == attrBytesList) {
            return;
        }
        //进行所有属性的解析
        for (byte[] attrBytes : attrBytesList) {
            int type = attrBytes[RadiusMsgAttr.INDEX_TYPE] & 0XFF;
            //判断属性类型是否合法
            if (!typeLegal(type, true)) {
                continue;
            }
            RadiusMsgAttr attr = RadiusMsgAttrParser.parse(attrBytes);
            //加入属性列表中
            if (null != attr) {
                this.attributes.add(attr);
            }
        }
    }

    @Override
    protected List<byte[]> getAttributesBytesList() {
        List<byte[]> list = new LinkedList<>();
        if (null != attributes) {
            for (RadiusMsgAttr attr : attributes) {
                int type = attr.getAttrType();
                if (!typeLegal(type, true)) {
                    continue;
                }
                byte[] bytes = bytes = attr.getBytes();
                if (null != bytes) {
                    list.add(bytes);
                }
            }
        }
        return list;
    }

}
